/*
    This file is part of Emu.

    Emu is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Emu is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Emu.  If not, see <http://www.gnu.org/licenses/>. */
#include <QGridLayout>
#include <QLabel>
#include <QVBoxLayout>

#include "ecolordefs.h"
#include "eprefbutton.h"
#include "edisplayeditor.h"
#include "colorlisteditor.h"

EDisplayEditor::EDisplayEditor(EProfile *prefsCopy, bool **colorChanges,
                               bool *anyChange)
{
    _profile = prefsCopy;
    _colorChanges = *colorChanges;
    _anyChange = anyChange;
    _colors = _profile->colors();

    QVBoxLayout *layout = new QVBoxLayout;

    QGroupBox *ansiBox = makeAnsiBox();
    QGroupBox *defaultsBox = makeDefaultsBox();

    layout->addWidget(ansiBox);
    layout->addWidget(defaultsBox);

    setLayout(layout);
}

void EDisplayEditor::applyPrefChanges()
{
    int i;

    for (i = 0;i < _ansiColorButtons.size();i++) {
        int id = _ansiColorButtons.at(i)->id();
        QColor oldColor = _colors[id];
        QColor newColor = _ansiColorButtons.at(i)->color();

        if (oldColor != newColor) {
            /* Remember that _colors is local. The changes need to be applied
               to the profile copy given for them to take. */
            _profile->setColor(id, newColor);
            *_anyChange = true;
            _colorChanges[id] = true;
        }
    }

    /* For ansi colors, the custom color picker is set to the ansi color that
       is currently selected. For custom ones, the color picker is the correct
       color. So...do the above again. */
    for (i = 0;i < _nonAnsiColorButtons.size();i++) {
        int id = _nonAnsiColorButtons.at(i)->id();
        QColor oldColor = _colors[id];
        QColor newColor = _nonAnsiColorButtons.at(i)->color();

        if (oldColor != newColor) {
            /* Remember that _colors is local. The changes need to be applied
               to the profile copy given for them to take. */
            _profile->setColor(id, newColor);
            *_anyChange = true;
            _colorChanges[id] = true;
        }
    }
}

QGroupBox *EDisplayEditor::makeAnsiBox()
{
    QBoxLayout *boxLayout = new QBoxLayout(QBoxLayout::LeftToRight);
    QGroupBox *gbox = new QGroupBox(tr("Ansi colors"));

    QVBoxLayout *labelColumn = new QVBoxLayout;
    QVBoxLayout *normalColumn = new QVBoxLayout;
    QVBoxLayout *boldColumn = new QVBoxLayout;
    QVBoxLayout *boldLabelColumn = new QVBoxLayout;

    QStringList colorNames = (QStringList() << "Black" << "Red" << "Green"
         << "Yellow" << "Blue" << "Magenta" << "Cyan" << "White");

    int i;
    /* There are seven normal colors, and seven bright colors. */
    for (i = 0;i <= 7;i++) {
        EPrefButton *normalButton =
                new EPrefButton(_colors[C_BLACK + i], C_BLACK + i);
        EPrefButton *boldButton =
                new EPrefButton(_colors[C_BOLD_BLACK + i], C_BOLD_BLACK + i);
        QLabel *colorLabel = new QLabel(colorNames.at(i));
        QLabel *boldColorLabel = new QLabel("Bold " + colorNames.at(i));

        connect(normalButton, SIGNAL(colorChanged(int, QColor)), this,
                SLOT(ansiColorChanged(int, QColor)));
        connect(boldButton, SIGNAL(colorChanged(int, QColor)), this,
                SLOT(ansiColorChanged(int, QColor)));
        _ansiColorButtons.append(normalButton);
        _ansiColorButtons.append(boldButton);

        labelColumn->addWidget(colorLabel, Qt::AlignCenter);
        normalColumn->addWidget(normalButton, Qt::AlignCenter);
        boldColumn->addWidget(boldButton, Qt::AlignCenter);
        boldLabelColumn->addWidget(boldColorLabel, Qt::AlignCenter);
    }

    boxLayout->addLayout(normalColumn);
    boxLayout->addLayout(labelColumn);
    boxLayout->insertStretch(2, 20);
    boxLayout->addLayout(boldColumn);
    boxLayout->addLayout(boldLabelColumn);
    boxLayout->insertStretch(5, 80);

    gbox->setLayout(boxLayout);
    return gbox;
}

/* When an ansi color changes, this is responsible for updating any ansi pickers
   and custom pickers using it.
   Remember to add one from id because the ansi pickers have the 'custom color'
   as the first item. */
void EDisplayEditor::ansiColorChanged(int id, QColor color)
{
    int i;
    for (i = 0;i < _nonAnsiColorButtons.size();i++) {
        _ansiPickers.at(i)->setItemData(id + 1, color, Qt::DecorationRole);

        /* If the ansi picker is using this color, then sync the custom color
           button too. */
        if (_ansiPickers.at(i)->currentIndex() == id + 1) {
            EPrefButton *colorButton = _nonAnsiColorButtons.at(i);
            colorButton->setEnabled(true);
            colorButton->setColor(color);
            colorButton->setEnabled(false);
        }
    }
}

void EDisplayEditor::pickerChanged(int id, int newIndex)
{
    int listIndex = id - C_NON_ANSI_START;
    EPrefButton *button = _nonAnsiColorButtons.at(listIndex);
    if (newIndex == 0)
        button->setEnabled(true);
    else {
        /* Enable it first, because color changes won't take while the button is
           disabled. */
        button->setEnabled(true);
        button->setColor(_ansiPickers.at(listIndex)->color());
        button->setEnabled(false);
    }
}

/* This handles making picker widgets for non-ansi colors. These colors get two
   widgets: A color selector which has ansi colors, and a custom color button.
   This allows users to easily specify that something uses a known ansi color
   (ex: Set foreground to ansi white, background to ansi black).
   These colors are intentionally unable to refer to each other to keep from a
   circular reference from occuring. */
QGroupBox *EDisplayEditor::makeDefaultsBox()
{
    QGroupBox *gbox = new QGroupBox(tr("Other"));
    QGridLayout *layout = new QGridLayout;

    QList<int> colorIndexes = QList<int>() << C_FOREGROUND << C_BACKGROUND
            << C_MSG_FOREGROUND << C_MSG_BACKGROUND;
    QList<QString> labelStrings = QList<QString>() << tr("Default Foreground")
            << tr("Default Background") << tr("Message Foreground")
            << tr("Message Background");

    int i;
    for (i = 0;i < labelStrings.size();i++) {
        int colorIndex = colorIndexes.at(i);
        QLabel *label = new QLabel(labelStrings.at(i));
        ColorListEditor *ansiPicker =
                new ColorListEditor(_profile, colorIndex);
        EPrefButton *customPicker =
                new EPrefButton(_colors[colorIndex], colorIndex);

        customPicker->setFixedSize(_ansiColorButtons.at(0)->sizeHint());
        _ansiPickers.append(ansiPicker);
        _nonAnsiColorButtons.append(customPicker);

        /* 0 is 'Custom Color'. If it's not using a custom color, then disable
           the custom picker. */
        if (ansiPicker->currentIndex() != 0) {
            customPicker->setColor(_colors[colorIndex]);
            customPicker->setEnabled(false);
        }

        connect(ansiPicker, SIGNAL(pickerIndexChanged(int, int)), this,
                SLOT(pickerChanged(int, int)));

        layout->addWidget(label, i, 0);
        layout->addWidget(ansiPicker, i, 1);
        layout->addWidget(customPicker, i, 2);
    }

    gbox->setLayout(layout);
    return gbox;
}
